﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MT4Trainer
{
    using System.Collections;
    using System.Reactive.Subjects;

    public class ObservableTrainings : IEnumerable<double>, ISubject<double>, IDisposable
    {
        public List<double> Errors = new List<double>();
        public int m_CurrentIteration;
        private Subject<double> easySubject = new Subject<double>();

        public int CurrentIteration
        {
            get
            {
                return m_CurrentIteration++;
            }
        }

        public void AddErrors(double last)
        {
            Errors.Add(last);
            this.OnNext(last);
        }

        #region Implementation of IEnumerable

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>1</filterpriority>
        public IEnumerator<double> GetEnumerator()
        {
            return this.Errors.GetEnumerator();
        }

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion Implementation of IEnumerable

        #region Implementation of IObserver<in double>

        /// <summary>
        /// Notifies the observer that the provider has finished sending push-based notifications.
        /// </summary>
        public void OnCompleted()
        {
            easySubject.OnCompleted();
            Console.WriteLine("On completed");
        }

        /// <summary>
        /// Notifies the observer that the provider has experienced an error condition.
        /// </summary>
        /// <param name="error">An object that provides additional information about the error.</param>
        public void OnError(Exception error)
        {
            easySubject.OnError(error);

            Console.WriteLine("Error :" + error);
        }

        /// <summary>
        /// Provides the observer with new data.
        /// </summary>
        /// <param name="value">The current notification information.</param>
        public void OnNext(double value)
        {
            easySubject.OnNext(value);
        }

        #endregion Implementation of IObserver<in double>

        #region Implementation of IObservable<out double>

        /// <summary>
        /// Notifies the provider that an observer is to receive notifications.
        /// </summary>
        /// <returns>
        /// The observer's interface that enables resources to be disposed.
        /// </returns>
        /// <param name="observer">The object that is to receive notifications.</param>
        public IDisposable Subscribe(IObserver<double> observer)
        {
            return easySubject.Subscribe(observer.OnNext, observer.OnError, observer.OnCompleted);
        }

        #endregion Implementation of IObservable<out double>

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            easySubject.Dispose();
        }

        #endregion Implementation of IDisposable
    }
}